package com.wangxs.cry.dec.annotion;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.wangxs.cry.dec.commom.ServiceResult;
import com.wangxs.cry.dec.utils.CryDecUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
public class CryDecToParamApo {

    /**
     * 加密：先进行Sm2非对称加密 -> 将加密数据进行Base64转码 -> 将得到的加密数据返回给前端
     * 解密：将获取到的数据先进行Base64转码 -> 将转码后的数据进行解密 -> 处理解密后的数据
     */


    @Pointcut("@annotation(com.wangxs.cry.dec.annotion.CryDecToParam)")
    public void point() {
    }

    @Around("point()")
    public Object cryDec(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();

        // 获取注解中的参数
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        CryDecToParam annotation = method.getAnnotation(CryDecToParam.class);

        // 解密
        if (CollectionUtil.isNotEmpty(Arrays.asList(args)) && annotation.requestDec()) {
            // base64解码
            String content =  new String( Base64.decodeBase64(String.valueOf(args[0]).replaceAll("\"", "")));
            // 进行解密操作
            String decryptStr = CryDecUtils.doSm2Decrypt(content);
            String result = decryptStr.replaceAll("\t", "").replaceAll("\n", "");
            // 传参赋值
            args[0] = result;
        }
        Object proceed = joinPoint.proceed(args);
        ServiceResult result = (ServiceResult) proceed;

        // 加密
        if (null != result.getData() && annotation.requestDec()) {
            // 加密
            String encryptStr = CryDecUtils.doSm2Cry(JSON.toJSONString(result.getData()));
            // 转码
            String response = Base64.encodeBase64String(encryptStr.getBytes());
            result.setData(response);
        }
        return proceed;
    }
}
